package org.hawk.gwt.ppc.reflect.lang;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.GenericDeclaration;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Constructor;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Field;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Method;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Type;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.TypeVariable;
import org.hawk.gwt.ppc.reflect.emul.org.hawk.gwt.ppc.reflect.lang.ReflectAccessor;

/**
 * Replaces default {@link java.lang.Class} for the GWT objects. Since direct
 * support of {@link Class} is not implemented it is only way to avoid compiler
 * errors and get all the functionality.
 * 
 * @author alex.bereznevatiy@gmail.com
 * 
 * @param <T>
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClassDelegate<T> implements GWTClassType<T> {
	public static final ClassDelegate VOID = new ClassDelegate(void.class);
	
	private static ReflectAccessor reflectAccessor = new ReflectAccessor();

	/**
	 * Wrappers for primitive types:
	 */
	public static final Map<Class<?>, Class<?>> WRAPPERS;

	static {
		Map<Class<?>, Class<?>> m = new HashMap<Class<?>, Class<?>>();
		m.put(boolean.class, Boolean.class);
		m.put(byte.class, Byte.class);
		m.put(double.class, Double.class);
		m.put(float.class, Float.class);
		m.put(int.class, Integer.class);
		m.put(long.class, Long.class);
		m.put(short.class, Short.class);
		m.put(char.class, Character.class);
		WRAPPERS = Collections.unmodifiableMap(m);
	}

	private ClassLoaderDelegate classLoader;
	private Class<T> clazz;
	private boolean reflectable;

	protected ClassDelegate(Class<T> clazz) {
		this.clazz = clazz;
	}
	
	/**
	 * Converts the object to a string. The string representation is the string
	 * "class" or "interface", followed by a space, and then by the fully
	 * qualified name of the class in the format returned by
	 * <code>getName</code>. If this <code>Class</code> object represents a
	 * primitive type, this method returns the name of the primitive type. If
	 * this <code>Class</code> object represents void this method returns
	 * "void".
	 * 
	 * @return a string representation of this class object.
	 */
	public String toString() {
		return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
				+ getName();
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.reflect.lang.GWTClassType#toClass()
	 */
	public Class<T> toClass() {
		return clazz;
	}

	/**
	 * Returns the <code>Class</code> object associated with the class or
	 * interface with the given string name. Invoking this method is equivalent
	 * to:
	 * 
	 * <blockquote>
	 * 
	 * <pre>
	 * Class.forName(className, true, currentLoader)
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * where <code>currentLoader</code> denotes the defining class loader of the
	 * current class.
	 * 
	 * <p>
	 * For example, the following code fragment returns the runtime
	 * <code>Class</code> descriptor for the class named
	 * <code>java.lang.Thread</code>:
	 * 
	 * <blockquote>
	 * 
	 * <pre>
	 *   Class&nbsp;t&nbsp;= Class.forName("java.lang.Thread")
	 * </pre>
	 * 
	 * </blockquote>
	 * <p>
	 * A call to <tt>forName("X")</tt> causes the class named <tt>X</tt> to be
	 * initialized.
	 * 
	 * @param className
	 *            the fully qualified name of the desired class.
	 * @return the <code>Class</code> object for the class with the specified
	 *         name.
	 * @exception LinkageError
	 *                if the linkage fails
	 * @exception ExceptionInInitializerError
	 *                if the initialization provoked by this method fails
	 * @exception ClassNotFoundException
	 *                if the class cannot be located
	 */
	public static ClassDelegate<?> forName(String className)
			throws ClassNotFoundException {
		return forName(className, false, SystemClassLoader.getInstance());
	}

	/**
	 * Returns the <code>Class</code> object associated with the class or
	 * interface with the given string name, using the given class loader. Given
	 * the fully qualified name for a class or interface (in the same format
	 * returned by <code>getName</code>) this method attempts to locate, load,
	 * and link the class or interface. The specified class loader is used to
	 * load the class or interface. If the parameter <code>loader</code> is
	 * null, the class is loaded through the bootstrap class loader. The class
	 * is initialized only if the <code>initialize</code> parameter is
	 * <code>true</code> and if it has not been initialized earlier.
	 * 
	 * <p>
	 * If <code>name</code> denotes a primitive type or void, an attempt will be
	 * made to locate a user-defined class in the unnamed package whose name is
	 * <code>name</code>. Therefore, this method cannot be used to obtain any of
	 * the <code>Class</code> objects representing primitive types or void.
	 * 
	 * <p>
	 * If <code>name</code> denotes an array class, the component type of the
	 * array class is loaded but not initialized.
	 * 
	 * <p>
	 * For example, in an instance method the expression:
	 * 
	 * <blockquote>
	 * 
	 * <pre>
	 * Class.forName(&quot;Foo&quot;)
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * is equivalent to:
	 * 
	 * <blockquote>
	 * 
	 * <pre>
	 * Class.forName(&quot;Foo&quot;, true, this.getClass().getClassLoader())
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * Note that this method throws errors related to loading, linking or
	 * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
	 * Java Language Specification</em>. Note that this method does not check
	 * whether the requested class is accessible to its caller.
	 * 
	 * <p>
	 * If the <code>loader</code> is <code>null</code>, and a security manager
	 * is present, and the caller's class loader is not null, then this method
	 * calls the security manager's <code>checkPermission</code> method with a
	 * <code>RuntimePermission("getClassLoader")</code> permission to ensure
	 * it's ok to access the bootstrap class loader.
	 * 
	 * @param name
	 *            fully qualified name of the desired class
	 * @param initialize
	 *            whether the class must be initialized
	 * @param loader
	 *            class loader from which the class must be loaded
	 * @return class object representing the desired class
	 * 
	 * @exception LinkageError
	 *                if the linkage fails
	 * @exception ExceptionInInitializerError
	 *                if the initialization provoked by this method fails
	 * @exception ClassNotFoundException
	 *                if the class cannot be located by the specified class
	 *                loader
	 * 
	 * @see java.lang.Class#forName(String)
	 * @see java.lang.ClassLoader
	 * @since 1.2
	 */
	public static ClassDelegate<?> forName(String name, boolean initialize,
			ClassLoaderDelegate loader) throws ClassNotFoundException {
		return loader.loadClass(name);
	}

	/**
	 * @param <T>
	 * @param cls
	 * @return the same as {@link ClassDelegate#forName(String)} but type-safe.
	 */
	public static <T> ClassDelegate<T> forClass(Class<T> cls) {
		if (cls == null) {
			return null;
		}
		if (cls.equals(Object.class)) {
			return (ClassDelegate<T>) ObjectClassDelegate.instance;
		}
		try {
			return (ClassDelegate<T>) forName(cls.getName());
		} catch (ClassNotFoundException ex) {
			ClassDelegate<T> rez = new ClassDelegate<T>(cls);
			rez.load(SystemClassLoader.getInstance(), false);
			return rez;
		}
	}

	/**
	 * Registers class loader for global context. {@link ClassLoaderDelegate} is
	 * GWT-valid replacement of {@link ClassLoader}. It replaces all necessary
	 * methods to avoid compilation problems, but not subclass
	 * {@link ClassLoader} itself to not conflict with GWT compiler.
	 * 
	 * @param classLoader
	 */
	public static void registerClassLoader(ClassLoaderDelegate classLoader) {
		SystemClassLoader.registerClassLoader(classLoader);
	}

	boolean isLoaded() {
		return classLoader != null;
	}

	void load(ClassLoaderDelegate classLoader, boolean reflectable) {
		this.classLoader = classLoader;
		this.reflectable = reflectable;
	}

	/**
	 * Creates a new instance of the class represented by this <tt>Class</tt>
	 * object. The class is instantiated as if by a <code>new</code> expression
	 * with an empty argument list. The class is initialized if it has not
	 * already been initialized.
	 * 
	 * <p>
	 * Note that this method propagates any exception thrown by the nullary
	 * constructor, including a checked exception. Use of this method
	 * effectively bypasses the compile-time exception checking that would
	 * otherwise be performed by the compiler. The
	 * {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...)
	 * Constructor.newInstance} method avoids this problem by wrapping any
	 * exception thrown by the constructor in a (checked)
	 * {@link java.lang.reflect.InvocationTargetException}.
	 * 
	 * @return a newly allocated instance of the class represented by this
	 *         object.
	 * @exception IllegalAccessException
	 *                if the class or its nullary constructor is not accessible.
	 * @exception InstantiationException
	 *                if this <code>Class</code> represents an abstract class,
	 *                an interface, an array class, a primitive type, or void;
	 *                or if the class has no nullary constructor; or if the
	 *                instantiation fails for some other reason.
	 * @exception ExceptionInInitializerError
	 *                if the initialization provoked by this method fails.
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
	 *                creation of new instances of this class
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 */
	public T newInstance() throws InstantiationException,
			IllegalAccessException {
		if (isInterface() || isEnum() || isAnnotation()) {
			throw new InstantiationException("Type " + toString() + " is not allowed to be instantiated.");
		}
		try {
			return getDeclaredConstructor().newInstance();
		} catch (InvocationTargetException e) {
			throw new InstantiationException(e.getMessage());
		} catch (NoSuchMethodException e) {
			throw new InstantiationException(e.getMessage());
		}
	}

	/**
	 * Determines if the specified <code>Object</code> is assignment-compatible
	 * with the object represented by this <code>Class</code>. This method is
	 * the dynamic equivalent of the Java language <code>instanceof</code>
	 * operator. The method returns <code>true</code> if the specified
	 * <code>Object</code> argument is non-null and can be cast to the reference
	 * type represented by this <code>Class</code> object without raising a
	 * <code>ClassCastException.</code> It returns <code>false</code> otherwise.
	 * 
	 * <p>
	 * Specifically, if this <code>Class</code> object represents a declared
	 * class, this method returns <code>true</code> if the specified
	 * <code>Object</code> argument is an instance of the represented class (or
	 * of any of its subclasses); it returns <code>false</code> otherwise. If
	 * this <code>Class</code> object represents an array class, this method
	 * returns <code>true</code> if the specified <code>Object</code> argument
	 * can be converted to an object of the array class by an identity
	 * conversion or by a widening reference conversion; it returns
	 * <code>false</code> otherwise. If this <code>Class</code> object
	 * represents an interface, this method returns <code>true</code> if the
	 * class or any superclass of the specified <code>Object</code> argument
	 * implements this interface; it returns <code>false</code> otherwise. If
	 * this <code>Class</code> object represents a primitive type, this method
	 * returns <code>false</code>.
	 * 
	 * @param obj
	 *            the object to check
	 * @return true if <code>obj</code> is an instance of this class
	 * 
	 * @since JDK1.1
	 */
	public boolean isInstance(Object obj) {
		if (obj == null) {
			return false;
		}
		String name = clazz.getName();
		if (LangClassLoader.isLangClass(name) || SystemClassLoader.isPrimitiveClass(name)) {
			return LangClassLoader.canCast(obj, clazz);
		}
		if (!reflectable) {
			return true;
		}
		return isAssignableFrom(obj.getClass());
	}

	/**
	 * Determines if the class or interface represented by this
	 * <code>Class</code> object is either the same as, or is a superclass or
	 * superinterface of, the class or interface represented by the specified
	 * <code>Class</code> parameter. It returns <code>true</code> if so;
	 * otherwise it returns <code>false</code>. If this <code>Class</code>
	 * object represents a primitive type, this method returns <code>true</code>
	 * if the specified <code>Class</code> parameter is exactly this
	 * <code>Class</code> object; otherwise it returns <code>false</code>.
	 * 
	 * <p>
	 * Specifically, this method tests whether the type represented by the
	 * specified <code>Class</code> parameter can be converted to the type
	 * represented by this <code>Class</code> object via an identity conversion
	 * or via a widening reference conversion. See <em>The Java Language
	 * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
	 * 
	 * @param cls
	 *            the <code>Class</code> object to be checked
	 * @return the <code>boolean</code> value indicating whether objects of the
	 *         type <code>cls</code> can be assigned to objects of this class
	 * @exception NullPointerException
	 *                if the specified Class parameter is null.
	 * @since JDK1.1
	 */
	public boolean isAssignableFrom(Class cls) {
		return isAssignableFrom(forClass(cls));
	}

	public boolean isAssignableFrom(ClassDelegate cls) { 
		if (cls == null) {
			throw new NullPointerException("Class is NULL");
		}
		if (isPrimitive() || cls.isPrimitive()) {
			return isAssignableFromPrimitive(cls);
		}
		if (cls.equals(this)) {
			return true;
		}
		if (cls.reflectable && cls.isAnnotation()) {
			return clazz.equals(Annotation.class);
		}
		if (cls.reflectable && isInterface()) {
			return cls.classLoader.checkIfClassIs(clazz, cls.getInterfacesIndices(new Accessor()));
		}
		while (cls.getSuperclass() != null) {
			if (equals(cls = cls.getSuperclass())) {
				return true;
			}
		}
		if (!cls.reflectable) {
			throw new UnsupportedOperationException("Unable to determine if class " + clazz + " is assignable from " + 
					cls.clazz + " because second class is not processed by preprocessor and so that it is unable to check " +
					"implemented interfaces of this class");
		}
		return false;
	}

	private boolean isAssignableFromPrimitive(ClassDelegate<?> cls) {
		if (!isPrimitive()) {
			return cls.isAssignableFromPrimitive(this);
		}
		if (clazz.equals(cls.clazz)) {
			return true;
		}
		if (WRAPPERS.get(clazz) == null) {
			return false;
		}
		return WRAPPERS.get(clazz).equals(cls.clazz);
	}

	/**
	 * Determines if the specified <code>Class</code> object represents an
	 * interface type.
	 * 
	 * @return <code>true</code> if this object represents an interface;
	 *         <code>false</code> otherwise.
	 */
	public boolean isInterface() {
		return clazz.isInterface();
	}

	/**
	 * Determines if this <code>Class</code> object represents an array class.
	 * 
	 * @return <code>true</code> if this object represents an array class;
	 *         <code>false</code> otherwise.
	 * @since JDK1.1
	 */
	public boolean isArray() {
		return clazz.isArray();
	}

	/**
	 * Determines if the specified <code>Class</code> object represents a
	 * primitive type.
	 * 
	 * <p>
	 * There are nine predefined <code>Class</code> objects to represent the
	 * eight primitive types and void. These are created by the Java Virtual
	 * Machine, and have the same names as the primitive types that they
	 * represent, namely <code>boolean</code>, <code>byte</code>,
	 * <code>char</code>, <code>short</code>, <code>int</code>,
	 * <code>long</code>, <code>float</code>, and <code>double</code>.
	 * 
	 * <p>
	 * These objects may only be accessed via the following public static final
	 * variables, and are the only <code>Class</code> objects for which this
	 * method returns <code>true</code>.
	 * 
	 * @return true if and only if this class represents a primitive type
	 * 
	 * @see java.lang.Boolean#TYPE
	 * @see java.lang.Character#TYPE
	 * @see java.lang.Byte#TYPE
	 * @see java.lang.Short#TYPE
	 * @see java.lang.Integer#TYPE
	 * @see java.lang.Long#TYPE
	 * @see java.lang.Float#TYPE
	 * @see java.lang.Double#TYPE
	 * @see java.lang.Void#TYPE
	 * @since JDK1.1
	 */
	public boolean isPrimitive() {
		return clazz.isPrimitive();
	}

	/**
	 * Returns true if this <tt>Class</tt> object represents an annotation type.
	 * Note that if this method returns true, {@link #isInterface()} would also
	 * return true, as all annotation types are also interfaces.
	 * 
	 * @return <tt>true</tt> if this class object represents an annotation type;
	 *         <tt>false</tt> otherwise
	 * @since 1.5
	 */
	public boolean isAnnotation() {
		if (!reflectable) {
			throw new UnsupportedOperationException();
		}
		return false;
	}

	/**
	 * Returns <tt>true</tt> if this class is a synthetic class; returns
	 * <tt>false</tt> otherwise.
	 * 
	 * @return <tt>true</tt> if and only if this class is a synthetic class as
	 *         defined by the Java Language Specification.
	 * @since 1.5
	 */
	public boolean isSynthetic() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns the name of the entity (class, interface, array class, primitive
	 * type, or void) represented by this <tt>Class</tt> object, as a
	 * <tt>String</tt>.
	 * 
	 * <p>
	 * If this class object represents a reference type that is not an array
	 * type then the binary name of the class is returned, as specified by the
	 * Java Language Specification, Second Edition.
	 * 
	 * <p>
	 * If this class object represents a primitive type or void, then the name
	 * returned is a <tt>String</tt> equal to the Java language keyword
	 * corresponding to the primitive type or void.
	 * 
	 * <p>
	 * If this class object represents a class of arrays, then the internal form
	 * of the name consists of the name of the element type preceded by one or
	 * more '<tt>[</tt>' characters representing the depth of the array nesting.
	 * The encoding of element type names is as follows:
	 * 
	 * <blockquote>
	 * <table summary="Element types and encodings">
	 * <tr>
	 * <th>Element Type
	 * <th>&nbsp;&nbsp;&nbsp;
	 * <th>Encoding
	 * <tr>
	 * <td>boolean
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>Z
	 * <tr>
	 * <td>byte
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>B
	 * <tr>
	 * <td>char
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>C
	 * <tr>
	 * <td>class or interface
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>L<i>classname</i>;
	 * <tr>
	 * <td>double
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>D
	 * <tr>
	 * <td>float
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>F
	 * <tr>
	 * <td>int
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>I
	 * <tr>
	 * <td>long
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>J
	 * <tr>
	 * <td>short
	 * <td>&nbsp;&nbsp;&nbsp;
	 * <td align=center>S
	 * </table>
	 * </blockquote>
	 * 
	 * <p>
	 * The class or interface name <i>classname</i> is the binary name of the
	 * class specified above.
	 * 
	 * <p>
	 * Examples: <blockquote>
	 * 
	 * <pre>
	 * String.class.getName()
	 *     returns "java.lang.String"
	 * byte.class.getName()
	 *     returns "byte"
	 * (new Object[3]).getClass().getName()
	 *     returns "[Ljava.lang.Object;"
	 * (new int[3][4][5][6][7][8][9]).getClass().getName()
	 *     returns "[[[[[[[I"
	 * </pre>
	 * 
	 * </blockquote>
	 * 
	 * @return the name of the class or interface represented by this object.
	 */
	public String getName() {
		return clazz.getName();
	}

	/**
	 * Returns the class loader for the class. Some implementations may use null
	 * to represent the bootstrap class loader. This method will return null in
	 * such implementations if this class was loaded by the bootstrap class
	 * loader.
	 * 
	 * <p>
	 * If a security manager is present, and the caller's class loader is not
	 * null and the caller's class loader is not the same as or an ancestor of
	 * the class loader for the class whose class loader is requested, then this
	 * method calls the security manager's <code>checkPermission</code> method
	 * with a <code>RuntimePermission("getClassLoader")</code> permission to
	 * ensure it's ok to access the class loader for the class.
	 * 
	 * <p>
	 * If this object represents a primitive type or void, null is returned.
	 * 
	 * @return the class loader that loaded the class or interface represented
	 *         by this object.
	 * @throws SecurityException
	 *             if a security manager exists and its
	 *             <code>checkPermission</code> method denies access to the
	 *             class loader for the class.
	 * @see java.lang.ClassLoader
	 * @see SecurityManager#checkPermission
	 * @see java.lang.RuntimePermission
	 */
	public ClassLoaderDelegate getClassLoader() {
		return classLoader;
	}

	/**
	 * Returns the <code>Class</code> representing the superclass of the entity
	 * (class, interface, primitive type or void) represented by this
	 * <code>Class</code>. If this <code>Class</code> represents either the
	 * <code>Object</code> class, an interface, a primitive type, or void, then
	 * null is returned. If this object represents an array class then the
	 * <code>Class</code> object representing the <code>Object</code> class is
	 * returned.
	 * 
	 * @return the superclass of the class represented by this object.
	 */
	public ClassDelegate<? super T> getSuperclass() {
		return forClass(clazz.getSuperclass());
	}

	/**
	 * Gets the package for this class. The class loader of this class is used
	 * to find the package. If the class was loaded by the bootstrap class
	 * loader the set of packages loaded from CLASSPATH is searched to find the
	 * package of the class. Null is returned if no package object was created
	 * by the class loader of this class.
	 * 
	 * <p>
	 * Packages have attributes for versions and specifications only if the
	 * information was defined in the manifests that accompany the classes, and
	 * if the class loader created the package instance with the attributes from
	 * the manifest.
	 * 
	 * @return the package of the class, or null if no package information is
	 *         available from the archive or codebase.
	 */
	public Package getPackage() {
		int i = getName().lastIndexOf('.');
		String name = "";
		if (i >= 0) {
			name = getName().substring(0, i);
		}
		return reflectAccessor.getPackage(name);
	}

	/**
	 * Determines the interfaces implemented by the class or interface
	 * represented by this object.
	 * 
	 * <p>
	 * If this object represents a class, the return value is an array
	 * containing objects representing all interfaces implemented by the class.
	 * The order of the interface objects in the array corresponds to the order
	 * of the interface names in the <code>implements</code> clause of the
	 * declaration of the class represented by this object. For example, given
	 * the declaration: <blockquote>
	 * 
	 * <pre>
	 * class Shimmer implements FloorWax, DessertTopping { ... }
	 * </pre>
	 * 
	 * </blockquote> suppose the value of <code>s</code> is an instance of
	 * <code>Shimmer</code>; the value of the expression: <blockquote>
	 * 
	 * <pre>
	 * s.getClass().getInterfaces()[0]
	 * </pre>
	 * 
	 * </blockquote> is the <code>Class</code> object that represents interface
	 * <code>FloorWax</code>; and the value of: <blockquote>
	 * 
	 * <pre>
	 * s.getClass().getInterfaces()[1]
	 * </pre>
	 * 
	 * </blockquote> is the <code>Class</code> object that represents interface
	 * <code>DessertTopping</code>.
	 * 
	 * <p>
	 * If this object represents an interface, the array contains objects
	 * representing all interfaces extended by the interface. The order of the
	 * interface objects in the array corresponds to the order of the interface
	 * names in the <code>extends</code> clause of the declaration of the
	 * interface represented by this object.
	 * 
	 * <p>
	 * If this object represents a class or interface that implements no
	 * interfaces, the method returns an array of length 0.
	 * 
	 * <p>
	 * If this object represents a primitive type or void, the method returns an
	 * array of length 0.
	 * 
	 * @return an array of interfaces implemented by this class.
	 */
	public ClassDelegate<?>[] getInterfaces() {
		return fromClasses(getImplementedInterfaces());
	}

	/**
	 * Returns the <code>Class</code> representing the component type of an
	 * array. If this class does not represent an array class this method
	 * returns null.
	 * 
	 * @return the <code>Class</code> representing the component type of this
	 *         class if this class is an array
	 * @see java.lang.reflect.Array
	 * @since JDK1.1
	 */
	public ClassDelegate<?> getComponentType() {
		return null;
	}

	/**
	 * Returns the Java language modifiers for this class or interface, encoded
	 * in an integer. The modifiers consist of the Java Virtual Machine's
	 * constants for <code>public</code>, <code>protected</code>,
	 * <code>private</code>, <code>final</code>, <code>static</code>,
	 * <code>abstract</code> and <code>interface</code>; they should be decoded
	 * using the methods of class <code>Modifier</code>.
	 * 
	 * <p>
	 * If the underlying class is an array class, then its <code>public</code>,
	 * <code>private</code> and <code>protected</code> modifiers are the same as
	 * those of its component type. If this <code>Class</code> represents a
	 * primitive type or void, its <code>public</code> modifier is always
	 * <code>true</code>, and its <code>protected</code> and
	 * <code>private</code> modifiers are always <code>false</code>. If this
	 * object represents an array class, a primitive type or void, then its
	 * <code>final</code> modifier is always <code>true</code> and its interface
	 * modifier is always <code>false</code>. The values of its other modifiers
	 * are not determined by this specification.
	 * 
	 * <p>
	 * The modifier encodings are defined in <em>The Java Virtual Machine
	 * Specification</em>, table 4.1.
	 * 
	 * @return the <code>int</code> representing the modifiers for this class
	 * @see java.lang.reflect.Modifier
	 * @since JDK1.1
	 */
	public int getModifiers() {
		return getModifiers(new Accessor(), "");
	}

	/**
	 * Gets the signers of this class.
	 * 
	 * @return the signers of this class, or null if there are no signers. In
	 *         particular, this method returns null if this object represents a
	 *         primitive type or void.
	 * @since JDK1.1
	 */
	public Object[] getSigners() {
		throw new UnsupportedOperationException();
	}

	/**
	 * If this <tt>Class</tt> object represents a local or anonymous class
	 * within a method, returns a {@link java.lang.reflect.Method Method} object
	 * representing the immediately enclosing method of the underlying class.
	 * Returns <tt>null</tt> otherwise.
	 * 
	 * In particular, this method returns <tt>null</tt> if the underlying class
	 * is a local or anonymous class immediately enclosed by a type declaration,
	 * instance initializer or static initializer.
	 * 
	 * @return the immediately enclosing method of the underlying class, if that
	 *         class is a local or anonymous class; otherwise <tt>null</tt>.
	 * @since 1.5
	 */
	public Method getEnclosingMethod() {
		throw new UnsupportedOperationException();
	}

	/**
	 * If this <tt>Class</tt> object represents a local or anonymous class
	 * within a constructor, returns a {@link java.lang.reflect.Constructor
	 * Constructor} object representing the immediately enclosing constructor of
	 * the underlying class. Returns <tt>null</tt> otherwise. In particular,
	 * this method returns <tt>null</tt> if the underlying class is a local or
	 * anonymous class immediately enclosed by a type declaration, instance
	 * initializer or static initializer.
	 * 
	 * @return the immediately enclosing constructor of the underlying class, if
	 *         that class is a local or anonymous class; otherwise <tt>null</tt>
	 *         .
	 * @since 1.5
	 */
	public Constructor<?> getEnclosingConstructor() {
		throw new UnsupportedOperationException();
	}

	/**
	 * If the class or interface represented by this <code>Class</code> object
	 * is a member of another class, returns the <code>Class</code> object
	 * representing the class in which it was declared. This method returns null
	 * if this class or interface is not a member of any other class. If this
	 * <code>Class</code> object represents an array class, a primitive type, or
	 * void,then this method returns null.
	 * 
	 * @return the declaring class for this class
	 * @since JDK1.1
	 */
	public ClassDelegate<?> getDeclaringClass() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns the immediately enclosing class of the underlying class. If the
	 * underlying class is a top level class this method returns <tt>null</tt>.
	 * 
	 * @return the immediately enclosing class of the underlying class
	 * @since 1.5
	 */
	public ClassDelegate<?> getEnclosingClass() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns the simple name of the underlying class as given in the source
	 * code. Returns an empty string if the underlying class is anonymous.
	 * 
	 * <p>
	 * The simple name of an array is the simple name of the component type with
	 * "[]" appended. In particular the simple name of an array whose component
	 * type is anonymous is "[]".
	 * 
	 * @return the simple name of the underlying class
	 * @since 1.5
	 */
	public String getSimpleName() {
		int i = getCanonicalName().lastIndexOf('.');
		if (i < 0)
			return getCanonicalName();
		return getCanonicalName().substring(i + 1);
	}

	/**
	 * Returns the canonical name of the underlying class as defined by the Java
	 * Language Specification. Returns null if the underlying class does not
	 * have a canonical name (i.e., if it is a local or anonymous class or an
	 * array whose component type does not have a canonical name).
	 * 
	 * @return the canonical name of the underlying class if it exists, and
	 *         <tt>null</tt> otherwise.
	 * @since 1.5
	 */
	public String getCanonicalName() {
		/*
		 * Since only top-level classes are supported this method always returns
		 * the same as #getName()
		 */
		return getName();
	}

	/**
	 * Returns <tt>true</tt> if and only if the underlying class is an anonymous
	 * class.
	 * 
	 * @return <tt>true</tt> if and only if this class is an anonymous class.
	 * @since 1.5
	 */
	public boolean isAnonymousClass() {
		return "".equals(getSimpleName());
	}

	/**
	 * Returns <tt>true</tt> if and only if the underlying class is a local
	 * class.
	 * 
	 * @return <tt>true</tt> if and only if this class is a local class.
	 * @since 1.5
	 */
	public boolean isLocalClass() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns <tt>true</tt> if and only if the underlying class is a member
	 * class.
	 * 
	 * @return <tt>true</tt> if and only if this class is a member class.
	 * @since 1.5
	 */
	public boolean isMemberClass() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns an array containing <code>Class</code> objects representing all
	 * the public classes and interfaces that are members of the class
	 * represented by this <code>Class</code> object. This includes public class
	 * and interface members inherited from superclasses and public class and
	 * interface members declared by the class. This method returns an array of
	 * length 0 if this <code>Class</code> object has no public member classes
	 * or interfaces. This method also returns an array of length 0 if this
	 * <code>Class</code> object represents a primitive type, an array class, or
	 * void.
	 * 
	 * @return the array of <code>Class</code> objects representing the public
	 *         members of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li>invocation of
	 *                <tt>{@link SecurityManager#checkMemberAccess
	 *             s.checkMemberAccess(this, Member.PUBLIC)}</tt> method denies
	 *                access to the classes within this class
	 * 
	 *                <li>the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of
	 *                <tt>{@link SecurityManager#checkPackageAccess
	 *             s.checkPackageAccess()}</tt> denies access to the package of
	 *                this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Class<?>[] getClasses() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns an array containing <code>Field</code> objects reflecting all the
	 * accessible public fields of the class or interface represented by this
	 * <code>Class</code> object. The elements in the array returned are not
	 * sorted and are not in any particular order. This method returns an array
	 * of length 0 if the class or interface has no accessible public fields, or
	 * if it represents an array class, a primitive type, or void.
	 * 
	 * <p>
	 * Specifically, if this <code>Class</code> object represents a class, this
	 * method returns the public fields of this class and of all its
	 * superclasses. If this <code>Class</code> object represents an interface,
	 * this method returns the fields of this interface and of all its
	 * superinterfaces.
	 * 
	 * <p>
	 * The implicit length field for array class is not reflected by this
	 * method. User code should use the methods of class <code>Array</code> to
	 * manipulate arrays.
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
	 * 
	 * @return the array of <code>Field</code> objects representing the public
	 *         fields
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
	 *                access to the fields within this class
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Field[] getFields() throws SecurityException {
		Map<String, Field> result = new TreeMap<String, Field>();
		addPublicFields(result, getDeclaredFields());
		ClassDelegate<?> sup = getSuperclass();
		if (sup != null) {
			addPublicFields(result, sup.getFields());
		}
		for (ClassDelegate<?> iFace : getInterfaces()) {
			addPublicFields(result, iFace.getFields());
		}
		return result.values().toArray(new Field[result.size()]);
	}

	private void addPublicFields(Map<String, Field> result, Field[] fields) {
		for (Field field : fields) {
			if (Modifier.isPublic(field.getModifiers())
					&& result.get(field.getName()) == null) {
				result.put(field.getName(), field);
			}
		}
	}

	/**
	 * Returns an array containing <code>Method</code> objects reflecting all
	 * the public <em>member</em> methods of the class or interface represented
	 * by this <code>Class</code> object, including those declared by the class
	 * or interface and those inherited from superclasses and superinterfaces.
	 * Array classes return all the (public) member methods inherited from the
	 * <code>Object</code> class. The elements in the array returned are not
	 * sorted and are not in any particular order. This method returns an array
	 * of length 0 if this <code>Class</code> object represents a class or
	 * interface that has no public member methods, or if this
	 * <code>Class</code> object represents a primitive type or void.
	 * 
	 * <p>
	 * The class initialization method <code>&lt;clinit&gt;</code> is not
	 * included in the returned array. If the class declares multiple public
	 * member methods with the same parameter types, they are all included in
	 * the returned array.
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
	 * 
	 * @return the array of <code>Method</code> objects representing the public
	 *         methods of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
	 *                access to the methods within this class
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Method[] getMethods() throws SecurityException {
		Map<String, Method> result = new TreeMap<String, Method>();
		addPublicMethods(result, getDeclaredMethods());
		ClassDelegate<?> sup = getSuperclass();
		if (sup != null) {
			addPublicMethods(result, sup.getMethods());
		}
		for (ClassDelegate<?> iFace : getInterfaces()) {
			addPublicMethods(result, iFace.getMethods());
		}
		return result.values().toArray(new Method[result.size()]);
	}

	private void addPublicMethods(Map<String, Method> result, Method[] methods) {
		for (Method method : methods) {
			if (Modifier.isPublic(method.getModifiers())
					&& result.get(getSignature(method)) == null) {
				result.put(getSignature(method), method);
			}
		}
	}

	/**
	 * Returns an array containing <code>Constructor</code> objects reflecting
	 * all the public constructors of the class represented by this
	 * <code>Class</code> object. An array of length 0 is returned if the class
	 * has no public constructors, or if the class is an array class, or if the
	 * class reflects a primitive type or void.
	 * 
	 * Note that while this method returns an array of {@code Constructor<T>}
	 * objects (that is an array of constructors from this class), the return
	 * type of this method is {@code Constructor<?>[]} and <em>not</em>
	 * {@code Constructor<T>[]} as might be expected. This less informative
	 * return type is necessary since after being returned from this method, the
	 * array could be modified to hold {@code Constructor} objects for different
	 * classes, which would violate the type guarantees of
	 * {@code Constructor<T>[]}.
	 * 
	 * @return the array of <code>Constructor</code> objects representing the
	 *         public constructors of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li>invocation of
	 *                <tt>{@link SecurityManager#checkMemberAccess
	 *             s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies access
	 *                to the constructors within this class
	 * 
	 *                <li>the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of
	 *                <tt>{@link SecurityManager#checkPackageAccess
	 *             s.checkPackageAccess()}</tt> denies access to the package of
	 *                this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Constructor<T>[] getConstructors() throws SecurityException {
		List<Constructor<T>> result = new LinkedList<Constructor<T>>();
		for (Constructor<T> c : getDeclaredConstructors()) {
			if (Modifier.isPublic(c.getModifiers())) {
				result.add(c);
			}
		}
		return result.toArray(new Constructor[result.size()]);
	}

	/**
	 * Returns a <code>Field</code> object that reflects the specified public
	 * member field of the class or interface represented by this
	 * <code>Class</code> object. The <code>name</code> parameter is a
	 * <code>String</code> specifying the simple name of the desired field.
	 * 
	 * <p>
	 * The field to be reflected is determined by the algorithm that follows.
	 * Let C be the class represented by this object:
	 * <OL>
	 * <LI>If C declares a public field with the name specified, that is the
	 * field to be reflected.</LI>
	 * <LI>If no field was found in step 1 above, this algorithm is applied
	 * recursively to each direct superinterface of C. The direct
	 * superinterfaces are searched in the order they were declared.</LI>
	 * <LI>If no field was found in steps 1 and 2 above, and C has a superclass
	 * S, then this algorithm is invoked recursively upon S. If C has no
	 * superclass, then a <code>NoSuchFieldException</code> is thrown.</LI>
	 * </OL>
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
	 * 
	 * @param name
	 *            the field name
	 * @return the <code>Field</code> object of this class specified by
	 *         <code>name</code>
	 * @exception NoSuchFieldException
	 *                if a field with the specified name is not found.
	 * @exception NullPointerException
	 *                if <code>name</code> is <code>null</code>
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
	 *                access to the field
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Field getField(String name) throws NoSuchFieldException,
			SecurityException {
		if (name == null) {
			throw new NullPointerException("Name is NULL");
		}
		for (Field field : getFields()) {
			if (field.getName().equals(name)) {
				return field;
			}
		}
		throw new NoSuchFieldException(name);
	}

	/**
	 * Returns a <code>Method</code> object that reflects the specified public
	 * member method of the class or interface represented by this
	 * <code>Class</code> object. The <code>name</code> parameter is a
	 * <code>String</code> specifying the simple name of the desired method. The
	 * <code>parameterTypes</code> parameter is an array of <code>Class</code>
	 * objects that identify the method's formal parameter types, in declared
	 * order. If <code>parameterTypes</code> is <code>null</code>, it is treated
	 * as if it were an empty array.
	 * 
	 * <p>
	 * If the <code>name</code> is "{@code <init>};"or "{@code <clinit>}" a
	 * <code>NoSuchMethodException</code> is raised. Otherwise, the method to be
	 * reflected is determined by the algorithm that follows. Let C be the class
	 * represented by this object:
	 * <OL>
	 * <LI>C is searched for any <I>matching methods</I>. If no matching method
	 * is found, the algorithm of step 1 is invoked recursively on the
	 * superclass of C.</LI>
	 * <LI>If no method was found in step 1 above, the superinterfaces of C are
	 * searched for a matching method. If any such method is found, it is
	 * reflected.</LI>
	 * </OL>
	 * 
	 * To find a matching method in a class C:&nbsp; If C declares exactly one
	 * public method with the specified name and exactly the same formal
	 * parameter types, that is the method reflected. If more than one such
	 * method is found in C, and one of these methods has a return type that is
	 * more specific than any of the others, that method is reflected; otherwise
	 * one of the methods is chosen arbitrarily.
	 * 
	 * <p>
	 * Note that there may be more than one matching method in a class because
	 * while the Java language forbids a class to declare multiple methods with
	 * the same signature but different return types, the Java virtual machine
	 * does not. This increased flexibility in the virtual machine can be used
	 * to implement various language features. For example, covariant returns
	 * can be implemented with {@linkplain java.lang.reflect.Method#isBridge
	 * bridge methods}; the bridge method and the method being overridden would
	 * have the same signature but different return types.
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
	 * 
	 * @param name
	 *            the name of the method
	 * @param parameterTypes
	 *            the list of parameters
	 * @return the <code>Method</code> object that matches the specified
	 *         <code>name</code> and <code>parameterTypes</code>
	 * @exception NoSuchMethodException
	 *                if a matching method is not found or if the name is
	 *                "&lt;init&gt;"or "&lt;clinit&gt;".
	 * @exception NullPointerException
	 *                if <code>name</code> is <code>null</code>
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
	 *                access to the method
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Method getMethod(String name, Class<?>... parameterTypes)
			throws SecurityException, NoSuchMethodException {
		return getMethod(name, fromClasses(parameterTypes));
	}

	public Method getMethod(String name, ClassDelegate<?>[] parameterTypes)
			throws NoSuchMethodException, SecurityException {
		if (name == null) {
			throw new NullPointerException("Name is NULL");
		}
		for (Method m : getMethods()) {
			if (m.getName().equals(name)
					&& typesEquals(parameterTypes, m.getParameterTypes())) {
				return m;
			}
		}
		throw new NoSuchMethodException(name + marshalSignature(parameterTypes));
	}

	private boolean typesEquals(Object[] types1, Object[] types2) {
		if (types1 == null && types2 == null) {
			return true;
		}
		if (types1 == null || types2 == null || types1.length != types2.length) {
			return false;
		}
		for (int i = 0; i < types1.length; i++) {
			ClassDelegate a;
			ClassDelegate b;

			if (types1[i] instanceof Class) {
				a = forClass((Class) types1[i]);
			} else {
				a = (ClassDelegate) types1[i];
			}

			if (types2[i] instanceof Class) {
				b = forClass((Class) types2[i]);
			} else {
				b = (ClassDelegate) types2[i];
			}

			if ((a == null && b != null) || (a != null && !a.equals(b))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Returns a <code>Constructor</code> object that reflects the specified
	 * public constructor of the class represented by this <code>Class</code>
	 * object. The <code>parameterTypes</code> parameter is an array of
	 * <code>Class</code> objects that identify the constructor's formal
	 * parameter types, in declared order.
	 * 
	 * If this <code>Class</code> object represents an inner class declared in a
	 * non-static context, the formal parameter types include the explicit
	 * enclosing instance as the first parameter.
	 * 
	 * <p>
	 * The constructor to reflect is the public constructor of the class
	 * represented by this <code>Class</code> object whose formal parameter
	 * types match those specified by <code>parameterTypes</code>.
	 * 
	 * @param parameterTypes
	 *            the parameter array
	 * @return the <code>Constructor</code> object of the public constructor
	 *         that matches the specified <code>parameterTypes</code>
	 * @exception NoSuchMethodException
	 *                if a matching method is not found.
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
	 *                access to the constructor
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Constructor<T> getConstructor(Class<?>... parameterTypes)
			throws SecurityException, NoSuchMethodException {
		return getConstructor(fromClasses(parameterTypes));
	}

	public Constructor<T> getConstructor(ClassDelegate<?>[] parameterTypes)
			throws NoSuchMethodException, SecurityException {
		for (Constructor<T> c : getConstructors()) {
			if (typesEquals(parameterTypes, c.getParameterTypes())) {
				return c;
			}
		}
		throw new NoSuchMethodException("There is no constructor " + getName()
				+ marshalSignature(parameterTypes));
	}

	/**
	 * Returns an array of <code>Class</code> objects reflecting all the classes
	 * and interfaces declared as members of the class represented by this
	 * <code>Class</code> object. This includes public, protected, default
	 * (package) access, and private classes and interfaces declared by the
	 * class, but excludes inherited classes and interfaces. This method returns
	 * an array of length 0 if the class declares no classes or interfaces as
	 * members, or if this <code>Class</code> object represents a primitive
	 * type, an array class, or void.
	 * 
	 * @return the array of <code>Class</code> objects representing all the
	 *         declared members of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li>invocation of
	 *                <tt>{@link SecurityManager#checkMemberAccess
	 *             s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared classes within this class
	 * 
	 *                <li>the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of
	 *                <tt>{@link SecurityManager#checkPackageAccess
	 *             s.checkPackageAccess()}</tt> denies access to the package of
	 *                this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Class<?>[] getDeclaredClasses() throws SecurityException {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns an array of <code>Field</code> objects reflecting all the fields
	 * declared by the class or interface represented by this <code>Class</code>
	 * object. This includes public, protected, default (package) access, and
	 * private fields, but excludes inherited fields. The elements in the array
	 * returned are not sorted and are not in any particular order. This method
	 * returns an array of length 0 if the class or interface declares no
	 * fields, or if this <code>Class</code> object represents a primitive type,
	 * an array class, or void.
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
	 * 
	 * @return the array of <code>Field</code> objects representing all the
	 *         declared fields of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared fields within this class
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Field[] getDeclaredFields() throws SecurityException {
		List<Field> result = new LinkedList<Field>();
		for (String signature : getFieldsSignatures()) {
			result.add(reflectAccessor.createField(new Accessor(), this,
					signature));
		}
		return result.toArray(new Field[result.size()]);
	}

	/**
	 * Returns an array of <code>Method</code> objects reflecting all the
	 * methods declared by the class or interface represented by this
	 * <code>Class</code> object. This includes public, protected, default
	 * (package) access, and private methods, but excludes inherited methods.
	 * The elements in the array returned are not sorted and are not in any
	 * particular order. This method returns an array of length 0 if the class
	 * or interface declares no methods, or if this <code>Class</code> object
	 * represents a primitive type, an array class, or void. The class
	 * initialization method <code>&lt;clinit&gt;</code> is not included in the
	 * returned array. If the class declares multiple public member methods with
	 * the same parameter types, they are all included in the returned array.
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, section 8.2.
	 * 
	 * @return the array of <code>Method</code> objects representing all the
	 *         declared methods of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared methods within this class
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Method[] getDeclaredMethods() throws SecurityException {
		List<Method> result = new LinkedList<Method>();
		Accessor accessor = new Accessor();
		for (String signature : getMethodSignatures()) {
			result.add(reflectAccessor.createMethod(accessor, this, signature, isVarArg(accessor, signature)));
		}
		return result.toArray(new Method[result.size()]);
	}

	/**
	 * Returns an array of <code>Constructor</code> objects reflecting all the
	 * constructors declared by the class represented by this <code>Class</code>
	 * object. These are public, protected, default (package) access, and
	 * private constructors. The elements in the array returned are not sorted
	 * and are not in any particular order. If the class has a default
	 * constructor, it is included in the returned array. This method returns an
	 * array of length 0 if this <code>Class</code> object represents an
	 * interface, a primitive type, an array class, or void.
	 * 
	 * <p>
	 * See <em>The Java Language Specification</em>, section 8.2.
	 * 
	 * @return the array of <code>Constructor</code> objects representing all
	 *         the declared constructors of this class
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li> invocation of <tt>
	 *                {@link SecurityManager#checkMemberAccess
	 *                s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared constructors within this class
	 * 
	 *                <li> the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of <tt>
	 *                {@link SecurityManager#checkPackageAccess
	 *                s.checkPackageAccess()}</tt> denies access to the package
	 *                of this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Constructor<T>[] getDeclaredConstructors() throws SecurityException {
		List<Constructor<T>> result = new LinkedList<Constructor<T>>();
		Accessor accessor = new Accessor();
		for (String signature : getConstructorSignatures()) {
			result.add(reflectAccessor.createConstructor(accessor, this,
					signature, isVarArg(accessor, signature)));
		}
		return result.toArray(new Constructor[result.size()]);
	}

	/**
	 * Returns a <code>Field</code> object that reflects the specified declared
	 * field of the class or interface represented by this <code>Class</code>
	 * object. The <code>name</code> parameter is a <code>String</code> that
	 * specifies the simple name of the desired field. Note that this method
	 * will not reflect the <code>length</code> field of an array class.
	 * 
	 * @param name
	 *            the name of the field
	 * @return the <code>Field</code> object for the specified field in this
	 *         class
	 * @exception NoSuchFieldException
	 *                if a field with the specified name is not found.
	 * @exception NullPointerException
	 *                if <code>name</code> is <code>null</code>
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li>invocation of
	 *                <tt>{@link SecurityManager#checkMemberAccess
	 *             s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared field
	 * 
	 *                <li>the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of
	 *                <tt>{@link SecurityManager#checkPackageAccess
	 *             s.checkPackageAccess()}</tt> denies access to the package of
	 *                this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Field getDeclaredField(String name) throws NoSuchFieldException,
			SecurityException {
		for (Field fld : getDeclaredFields()) {
			if (fld.getName().equals(name)) {
				return fld;
			}
		}
		throw new NoSuchFieldException(name);
	}

	/**
	 * Returns a <code>Method</code> object that reflects the specified declared
	 * method of the class or interface represented by this <code>Class</code>
	 * object. The <code>name</code> parameter is a <code>String</code> that
	 * specifies the simple name of the desired method, and the
	 * <code>parameterTypes</code> parameter is an array of <code>Class</code>
	 * objects that identify the method's formal parameter types, in declared
	 * order. If more than one method with the same parameter types is declared
	 * in a class, and one of these methods has a return type that is more
	 * specific than any of the others, that method is returned; otherwise one
	 * of the methods is chosen arbitrarily. If the name is "&lt;init&gt;"or
	 * "&lt;clinit&gt;" a <code>NoSuchMethodException</code> is raised.
	 * 
	 * @param name
	 *            the name of the method
	 * @param parameterTypes
	 *            the parameter array
	 * @return the <code>Method</code> object for the method of this class
	 *         matching the specified name and parameters
	 * @exception NoSuchMethodException
	 *                if a matching method is not found.
	 * @exception NullPointerException
	 *                if <code>name</code> is <code>null</code>
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li>invocation of
	 *                <tt>{@link SecurityManager#checkMemberAccess
	 *             s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared method
	 * 
	 *                <li>the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of
	 *                <tt>{@link SecurityManager#checkPackageAccess
	 *             s.checkPackageAccess()}</tt> denies access to the package of
	 *                this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
			throws SecurityException, NoSuchMethodException {
		return getDeclaredMethod(name, fromClasses(parameterTypes));
	}

	public Method getDeclaredMethod(String name,
			ClassDelegate<?>[] parameterTypes) throws NoSuchMethodException,
			SecurityException {
		if (name == null) {
			throw new NullPointerException("Name is NULL");
		}
		for (Method m : getDeclaredMethods()) {
			if (m.getName().equals(name)
					&& typesEquals(parameterTypes, m.getParameterTypes())) {
				return m;
			}
		}
		throw new NoSuchMethodException(name + marshalSignature(parameterTypes));
	}

	/**
	 * Returns a <code>Constructor</code> object that reflects the specified
	 * constructor of the class or interface represented by this
	 * <code>Class</code> object. The <code>parameterTypes</code> parameter is
	 * an array of <code>Class</code> objects that identify the constructor's
	 * formal parameter types, in declared order.
	 * 
	 * If this <code>Class</code> object represents an inner class declared in a
	 * non-static context, the formal parameter types include the explicit
	 * enclosing instance as the first parameter.
	 * 
	 * @param parameterTypes
	 *            the parameter array
	 * @return The <code>Constructor</code> object for the constructor with the
	 *         specified parameter list
	 * @exception NoSuchMethodException
	 *                if a matching method is not found.
	 * @exception SecurityException
	 *                If a security manager, <i>s</i>, is present and any of the
	 *                following conditions is met:
	 * 
	 *                <ul>
	 * 
	 *                <li>invocation of
	 *                <tt>{@link SecurityManager#checkMemberAccess
	 *             s.checkMemberAccess(this, Member.DECLARED)}</tt> denies
	 *                access to the declared constructor
	 * 
	 *                <li>the caller's class loader is not the same as or an
	 *                ancestor of the class loader for the current class and
	 *                invocation of
	 *                <tt>{@link SecurityManager#checkPackageAccess
	 *             s.checkPackageAccess()}</tt> denies access to the package of
	 *                this class
	 * 
	 *                </ul>
	 * 
	 * @since JDK1.1
	 */
	public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
			throws SecurityException, NoSuchMethodException {
		return getDeclaredConstructor(fromClasses(parameterTypes));
	}

	public Constructor<T> getDeclaredConstructor(
			ClassDelegate<?>[] parameterTypes) throws NoSuchMethodException,
			SecurityException {
		for (Constructor<T> c : getDeclaredConstructors()) {
			if (typesEquals(parameterTypes, c.getParameterTypes())) {
				return c;
			}
		}
		throw new NoSuchMethodException("There is no constructor " + getName()
				+ marshalSignature(parameterTypes));
	}

	/**
	 * Returns the assertion status that would be assigned to this class if it
	 * were to be initialized at the time this method is invoked. If this class
	 * has had its assertion status set, the most recent setting will be
	 * returned; otherwise, if any package default assertion status pertains to
	 * this class, the most recent setting for the most specific pertinent
	 * package default assertion status is returned; otherwise, if this class is
	 * not a system class (i.e., it has a class loader) its class loader's
	 * default assertion status is returned; otherwise, the system class default
	 * assertion status is returned.
	 * <p>
	 * Few programmers will have any need for this method; it is provided for
	 * the benefit of the JRE itself. (It allows a class to determine at the
	 * time that it is initialized whether assertions should be enabled.) Note
	 * that this method is not guaranteed to return the actual assertion status
	 * that was (or will be) associated with the specified class when it was (or
	 * will be) initialized.
	 * 
	 * @return the desired assertion status of the specified class.
	 * @see java.lang.ClassLoader#setClassAssertionStatus
	 * @see java.lang.ClassLoader#setPackageAssertionStatus
	 * @see java.lang.ClassLoader#setDefaultAssertionStatus
	 * @since 1.4
	 */
	public boolean desiredAssertionStatus() {
		return clazz.desiredAssertionStatus();
	}

	/**
	 * Returns true if and only if this class was declared as an enum in the
	 * source code.
	 * 
	 * @return true if and only if this class was declared as an enum in the
	 *         source code
	 * @since 1.5
	 */
	public boolean isEnum() {
		return clazz.isEnum();
	}

	/**
	 * Returns the elements of this enum class or null if this Class object does
	 * not represent an enum type.
	 * 
	 * @return an array containing the values comprising the enum class
	 *         represented by this Class object in the order they're declared,
	 *         or null if this Class object does not represent an enum type
	 * @since 1.5
	 */
	public T[] getEnumConstants() {
		return clazz.getEnumConstants();
	}

	/**
	 * Casts an object to the class or interface represented by this
	 * <tt>Class</tt> object.
	 * 
	 * @param obj
	 *            the object to be cast
	 * @return the object after casting, or null if obj is null
	 * 
	 * @throws ClassCastException
	 *             if the object is not null and is not assignable to the type
	 *             T.
	 * 
	 * @since 1.5
	 */
	public T cast(Object obj) {
		if (obj != null && !isInstance(obj))
			throw new ClassCastException();
		return (T) obj;
	}

	/**
	 * Casts this <tt>Class</tt> object to represent a subclass of the class
	 * represented by the specified class object. Checks that that the cast is
	 * valid, and throws a <tt>ClassCastException</tt> if it is not. If this
	 * method succeeds, it always returns a reference to this class object.
	 * 
	 * <p>
	 * This method is useful when a client needs to "narrow" the type of a
	 * <tt>Class</tt> object to pass it to an API that restricts the
	 * <tt>Class</tt> objects that it is willing to accept. A cast would
	 * generate a compile-time warning, as the correctness of the cast could not
	 * be checked at runtime (because generic types are implemented by erasure).
	 * 
	 * @return this <tt>Class</tt> object, cast to represent a subclass of the
	 *         specified class object.
	 * @throws ClassCastException
	 *             if this <tt>Class</tt> object does not represent a subclass
	 *             of the specified class (here "subclass" includes the class
	 *             itself).
	 * @since 1.5
	 */
	public <U> ClassDelegate<? extends U> asSubclass(ClassDelegate<U> clazz) {
		if (clazz.isAssignableFrom(this))
			return (ClassDelegate<? extends U>) this;
		else
			throw new ClassCastException(this.toString());
	}
	/**
	 * Casts this <tt>Class</tt> object to represent a subclass of the class
	 * represented by the specified class object. Checks that that the cast is
	 * valid, and throws a <tt>ClassCastException</tt> if it is not. If this
	 * method succeeds, it always returns a reference to this class object.
	 * 
	 * <p>
	 * This method is useful when a client needs to "narrow" the type of a
	 * <tt>Class</tt> object to pass it to an API that restricts the
	 * <tt>Class</tt> objects that it is willing to accept. A cast would
	 * generate a compile-time warning, as the correctness of the cast could not
	 * be checked at runtime (because generic types are implemented by erasure).
	 * 
	 * @return this <tt>Class</tt> object, cast to represent a subclass of the
	 *         specified class object.
	 * @throws ClassCastException
	 *             if this <tt>Class</tt> object does not represent a subclass
	 *             of the specified class (here "subclass" includes the class
	 *             itself).
	 * @since 1.5
	 */
	public <U> Class<? extends U> asSubclass(Class<U> clazz) {
		return asSubclass(forClass(clazz)).toClass();
	}

	/**
	 * @throws NullPointerException
	 *             {@inheritDoc}
	 * @since 1.5
	 */
	public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
		throw new UnsupportedOperationException();
	}

	/**
	 * @throws NullPointerException
	 *             {@inheritDoc}
	 * @since 1.5
	 */
	public boolean isAnnotationPresent(
			Class<? extends Annotation> annotationClass) {
		throw new UnsupportedOperationException();
	}

	/**
	 * @since 1.5
	 */
	public Annotation[] getAnnotations() {
		throw new UnsupportedOperationException();
	}

	/**
	 * @since 1.5
	 */
	public Annotation[] getDeclaredAnnotations() {
		throw new UnsupportedOperationException();
	}
	/**
     * Returns an array of <tt>TypeVariable</tt> objects that represent the
     * type variables declared by the generic declaration represented by this
     * <tt>GenericDeclaration</tt> object, in declaration order.  Returns an
     * array of length 0 if the underlying generic declaration declares no type
     * variables.
     *
     * @return an array of <tt>TypeVariable</tt> objects that represent
     *     the type variables declared by this generic declaration
     * @throws GenericSignatureFormatError if the generic
     *     signature of this generic declaration does not conform to
     *     the format specified in the Java Virtual Machine Specification,
     *     3rd edition
     * @since 1.5
     */
	public TypeVariable<GWTClassType<T>>[] getTypeParameters() {
		thereIsNoGenericSupport();
		return null;
	}
	
	protected final GWTTypeVariable getTypeParameter(GenericDeclaration declarator, String name, Object...bounds) {
		return new GWTTypeVariable(new Accessor(), declarator, name, bounds);
	}
	
	/**
     * Returns the <tt>Type</tt> representing the direct superclass of
     * the entity (class, interface, primitive type or void) represented by
     * this <tt>Class</tt>.
     * 
     * <p>If the superclass is a parameterized type, the <tt>Type</tt>
     * object returned must accurately reflect the actual type
     * parameters used in the source code. The parameterized type
     * representing the superclass is created if it had not been
     * created before. See the declaration of {@link
     * java.lang.reflect.ParameterizedType ParameterizedType} for the
     * semantics of the creation process for parameterized types.  If
     * this <tt>Class</tt> represents either the <tt>Object</tt>
     * class, an interface, a primitive type, or void, then null is
     * returned.  If this object represents an array class then the
     * <tt>Class</tt> object representing the <tt>Object</tt> class is
     * returned.
     *
     * @throws GenericSignatureFormatError if the generic
     *     class signature does not conform to the format specified in the
     *     Java Virtual Machine Specification, 3rd edition
     * @throws TypeNotPresentException if the generic superclass
     *     refers to a non-existent type declaration
     * @throws MalformedParameterizedTypeException if the 
     *     generic superclass refers to a parameterized type that cannot be
     *     instantiated  for any reason
     * @return the superclass of the class represented by this object
     * @since 1.5
     */
    public Type getGenericSuperclass() {
    	Object result = getGenericSuperclass(new Accessor(), false);
    	if (result instanceof Class) {
    		return forClass((Class<?>)result);
    	}
    	return (Type)result;
    }
    
    /**
     * Returns the <tt>Type</tt>s representing the interfaces 
     * directly implemented by the class or interface represented by
     * this object.
     *
     * <p>If a superinterface is a parameterized type, the
     * <tt>Type</tt> object returned for it must accurately reflect
     * the actual type parameters used in the source code. The
     * parameterized type representing each superinterface is created
     * if it had not been created before. See the declaration of
     * {@link java.lang.reflect.ParameterizedType ParameterizedType}
     * for the semantics of the creation process for parameterized
     * types.
     *
     * <p> If this object represents a class, the return value is an
     * array containing objects representing all interfaces
     * implemented by the class. The order of the interface objects in
     * the array corresponds to the order of the interface names in
     * the <tt>implements</tt> clause of the declaration of the class
     * represented by this object.  In the case of an array class, the
     * interfaces <tt>Cloneable</tt> and <tt>Serializable</tt> are
     * returned in that order.
     *
     * <p>If this object represents an interface, the array contains
     * objects representing all interfaces directly extended by the
     * interface.  The order of the interface objects in the array
     * corresponds to the order of the interface names in the
     * <tt>extends</tt> clause of the declaration of the interface
     * represented by this object.
     *
     * <p>If this object represents a class or interface that
     * implements no interfaces, the method returns an array of length
     * 0.
     *
     * <p>If this object represents a primitive type or void, the
     * method returns an array of length 0.
     *
     * @throws GenericSignatureFormatError
     *     if the generic class signature does not conform to the format
     *     specified in the Java Virtual Machine Specification, 3rd edition
     * @throws TypeNotPresentException if any of the generic
     *     superinterfaces refers to a non-existent type declaration
     * @throws MalformedParameterizedTypeException if any of the 
     *     generic superinterfaces refer to a parameterized type that cannot
     *     be instantiated  for any reason
     * @return an array of interfaces implemented by this class
     * @since 1.5
     */
    public Type[] getGenericInterfaces() {
    	Object[] result = getGenericInterfaces(new Accessor(), false);
    	Type[] resultPlain = new Type[result.length];
    	for (int i = 0; i < result.length; i++) {
    		if (result[i] instanceof Class) {
    			resultPlain[i] = forClass((Class)result[i]);
    		} else {
    			resultPlain[i] = (Type)result[i];
    		}
    	}
    	return resultPlain;
    }

	private void thereIsNoGenericSupport() {
		throw new UnsupportedOperationException("Generics are turned off. " +
				"Please refer to the preprocessor command line options to find out how to turn on generic support.");
	}

	private String getSignature(Method method) {
		return method.getName() + argumentTypesToString(method.getParameterTypes());
	}

	private static ClassDelegate[] fromClasses(Class[] classes) {
		ClassDelegate[] result = new ClassDelegate[classes.length];
		for (int i = 0; i < classes.length; i++) {
			result[i] = forClass(classes[i]);
		}
		return result;
	}

	private static String argumentTypesToString(Class<?>[] argTypes) {
		StringBuilder buf = new StringBuilder();
		buf.append("(");
		if (argTypes != null) {
			for (int i = 0; i < argTypes.length; i++) {
				if (i > 0) {
					buf.append(',');
				}
				Class<?> c = argTypes[i];
				buf.append((c == null) ? "null" : c.getName());
			}
		}
		buf.append(")");
		return buf.toString();
	}

	public static String marshalSignature(ClassDelegate<?>[] argTypes) {
		Class<?>[] argdTypes = new Class[argTypes.length];
		for (int i = 0; i < argTypes.length; i++) {
			argdTypes[i] = argTypes[i].toClass();
		}
		return argumentTypesToString(argdTypes);
	}

	public static Class<?>[] unmarshalSignature(String signature) {
		int start = signature.lastIndexOf('(') + 1;
		int end = signature.lastIndexOf(')');
		if (start < 0 || end < 0) {
			return new Class<?>[0];
		}
		signature = signature.substring(start, end).trim();
		if (signature.length() == 0) {
			return new Class<?>[0];
		}
		String[] tmp = signature.split(",");
		Class<?>[] result = new Class<?>[tmp.length];
		for (int i = 0; i < tmp.length; i++) {
			try {
				result[i] = ClassDelegate.forName(normalizeType(tmp[i])).toClass();
			} catch (ClassNotFoundException e) {
				throw new InternalError("ClassNotFoundException:"
						+ e.getMessage());
			}
		}
		return result;
	}

	private static String normalizeType(String name) {
		if (!name.endsWith("[]")) {
			return name;
		}
		return SystemClassLoader.getArrayTypeName(name.substring(0, name.length() - 2));
	}

	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if (obj == this)
			return true;
		if (obj instanceof ClassDelegate) {
			return ((ClassDelegate<?>) obj).clazz.equals(clazz);
		}
		if (obj instanceof Class) {
			return ((Class<?>) obj).equals(clazz);
		}
		return super.equals(obj);
	}

	/**
	 * For internal use. Provides access to private
	 * org.hawk.gwt.ppc.reflect.emul.java.lang.reflect package.
	 */
	private static final class Accessor {
		private Accessor() {
		}
	}

	/*
	 * Next methods should be overridden by specific classes.
	 */
	protected Class<?>[] getImplementedInterfaces() {
		return new Class[0];
	}

	protected String[] getConstructorSignatures() {
		return new String[0];
	}

	protected String[] getFieldsSignatures() {
		return new String[0];
	}

	protected String[] getMethodSignatures() {
		return new String[0];
	}

	public int getModifiers(Object accessor, String signature) {
		checkAccessor(accessor);
		return 0;
	}

	public T create(Object accessor, String signature, Object[] initargs) throws Throwable {
		checkAccessor(accessor);
		return null;
	}

	public Class<?> getFieldType(Object accessor, String name) {
		checkAccessor(accessor);
		return null;
	}

	public Object get(Object accessor, String name, Object obj) {
		checkAccessor(accessor);
		return null;
	}

	public void set(Object accessor, String name, Object obj, Object value) {
		checkAccessor(accessor);
	}

	public Class<?> getReturnType(Object accessor, String signature) {
		checkAccessor(accessor);
		return null;
	}

	public Object invoke(Object accessor, String signature, Object obj,
			Object[] parameters) throws Throwable {
		checkAccessor(accessor);
		return null;
	}
	
	public Object createArray(Object accessor, int[] dimensions) {
		if (accessor == null || !(accessor instanceof Array)) {
			throw new IllegalAccessError(
					"You are not allowed to call this method");
		}
		if (dimensions.length > 5) {
			throw new InternalError("GWT preprocessor cannot create arrays with more than 5 dimensions. Please contact preprocessor support");
		}
		return null;
	}

    protected Object[] getGenericInterfaces(Object accessor, boolean allow) {
    	if (!allow) {
    		thereIsNoGenericSupport();
    	}
    	checkAccessor(accessor);
    	return null;
    }
    
    protected Object getGenericSuperclass(Object accessor, boolean allow) {
    	if (!allow) {
    		thereIsNoGenericSupport();
    	}
    	checkAccessor(accessor);
    	return null;
    }
    
    public <G extends GenericDeclaration> GWTTypeVariable<G>[] getMethodTypeParameters(G m, Object accessor, String signature) {
    	checkAccessor(accessor);
		return null;
	}
    
    public Type[] getMethodGenericParameterTypes(GenericDeclaration declaration, Object accessor, String signature) {
    	checkAccessor(accessor);
    	return null;
    }
    
    protected boolean isVarArg(Object accessor, String signature) {
    	checkAccessor(accessor);
    	return false;
    }

	protected int[] getInterfacesIndices(Object accessor) {
		checkAccessor(accessor);
		return new int[0];
	}

	public Type getGenericReturnType(Method declaration, Object accessor, String signature) {
		checkAccessor(accessor);
		return null;
	}

	public Type getGenericFieldType(Object accessor, String name) {
		checkAccessor(accessor);
		return null;
	}
	
	private void checkAccessor(Object accessor) throws IllegalAccessError {
		if (accessor == null || !(accessor instanceof Accessor)) {
			throw new IllegalAccessError("You are not allowed to call this method");
		}
	}
}
